/*
 ID: brodyzt
 PROG: namenum
 LANG: C++
 */

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <math.h>
#include <stdlib.h>
#include <vector>

using namespace std;

string intToString (int origNum)
{
    stringstream tempStream;
    tempStream << origNum;
    string tempString;
    tempStream >> tempString;
    return tempString;
}

bool arrayIsSorted (vector<int> array)
{
    bool isSorted = true;
    for (int i = 0; i < array.size() - 1; i++) {
        if (array[i] > array[i+1]) {
            isSorted = false;
            break;
        }
    }
    return isSorted;
}
vector<int> swapItems (int index1, int index2, vector<int> array)
{
    int temp;
    temp = array[index1];
    array[index1] = array[index2];
    array[index2] = temp;
    return array;
}

vector<int> bubbleSort (vector<int> array)
{
    while (!arrayIsSorted(array)) {
        for (int i = 0; i < array.size() - 1; i++) {
            if (array[i] > array[i+1]) {
                array = swapItems(i, i+1, array);
            }
        }
        
    }
    return array;
}

int factorial(int number) {
	int temp;
    
	if(number <= 1) return 1;
    
	temp = number * factorial(number - 1);
	return temp;
}

bool isInList (int item, vector<int> list, int length)
{
    for (int i = 0; i < length; i++) {
        if(item == list[i])
        {
            return true;
        }
    }
    return false;
}

int swappedItems (int num, int index1, int index2)
{
    string tempString = intToString(num);
    char tempChar;
    tempChar = tempString [index1];
    tempString[index1] = tempString[index2];
    tempString[index2] = tempChar;
    int newNum;
    istringstream (tempString) >> newNum;
    return newNum;
}

vector<int> calcPossibleNumVaritations (int num)
{
    vector<int> possibleValues;
    int length;
    length = 0;
    int tempCombo = swappedItems(num, rand() % (intToString(num).length() - 1), rand() % (intToString(num).length() - 1));
    while (length < factorial(num)) {
        tempCombo = swappedItems(tempCombo, rand() % (intToString(num).length() - 1), rand() % (intToString(num).length() - 1));
        if (!isInList(tempCombo, possibleValues, length)) {
            possibleValues.push_back(tempCombo);
            length +=1;
        }
    }
    
    //possibleValues = bubbleSort(possibleValues);
    return possibleValues;
}

int nameToNum (string name, char decoder[8][3])
{
    int num = 0;
    for (int i = 0; i < name.length(); i++) {
        for (int j = 0; j < 8; j++) {
            for (int k = 0; k < 3; k++) {
                if (name[i] == decoder[j][k]) {
                    num += pow(10, (int)name.length() - (i + 1)) * (j + 2);
                }
            }
        }
    }
    return num;
}




int main(int argc, const char * argv[])
{
  
    ifstream input("namenum.in");
    int origNum;
    input >> origNum;
    input.close();
    ifstream dictionary;
    dictionary.open("dict.txt");
    vector<int> names;
    char numAssignments[8][3] = {
        {'A','B','C'},
        {'D','E','F'},
        {'G','H','I'},
        {'J','K','L'},
        {'M','N','O'},
        {'P','R','S'},
        {'T','U','V'},
        {'W','X','Y'}
    };
    ofstream output("namenum.out");
    vector<int> possibleNums = calcPossibleNumVaritations(500);
    cout << possibleNums.size();
    for (int i = 0; i < 4617; i++) {
        string tempstring;
        dictionary >> tempstring;
        names.push_back(nameToNum(tempstring, numAssignments));
        if (isInList(nameToNum(tempstring, numAssignments), possibleNums, (int)possibleNums.size())) {
            output << tempstring << "\n";
        }
    }
    dictionary.close();
    output.close();
    
    
    return 0;
}

